import re
import os
from pymongo import MongoClient
from bson import ObjectId
from datetime import datetime
import chardet
import json
from datetime import datetime
# 连接到MongoDB数据库
client = MongoClient('mongodb://localhost:27017/')
db = client['lilyweb']
law_items_collection = db.lawitems
# 打开文件
path = ("E:\法律\法律文件\中华人民共和国证券法.txt")
with open(path, 'rb') as f:
    raw = f.read()
encoding = chardet.detect(raw)['encoding']
with open(path, 'r', encoding=encoding) as file:
    lines = file.readlines()
    
# 使用 re.MULTILINE 使得 ^ 匹配每一行的开始
pattern = re.compile(r'^(第[\u4e00-\u9fa5]+条).*', re.MULTILINE)

commented_lines = []
with open(path, 'r', encoding=encoding) as file:
    for line in file:
        if pattern.match(line) and not line.strip().startswith('#'):  # 确保行首是“第X条”且行首没有#
            commented_line = '# ' + line  # 在行前添加'#'
            commented_lines.append(commented_line)
        else:
            commented_lines.append(line)

# 将处理后的行写回文件（可选）
with open(path, 'w', encoding=encoding) as file:
    file.writelines(commented_lines)

#重新打开文件
with open(path, 'rb') as f:
    raw = f.read()
encoding = chardet.detect(raw)['encoding']
with open(path, 'r', encoding=encoding) as file:
    lines = file.readlines()
# lines 是一个列表，其中每个元素是文件中的一行
content = ''.join(lines)
content = re.sub(r'-', '#', content)
content = re.sub(r'\u3000',' ', content)
content = re.sub(r'\xa0',' ',content)
# 定义一个正则表达式，匹配形如 **第N条** 的文本
pattern = re.compile(r'\*\*第([\u4e00-\u9fa5]+)条\*\*')

    # 定义替换函数，将匹配到的文本替换为 "# 第N条"
def replacer(match):
    return f"# 第{match.group(1)}条"

    # 使用 re.sub 函数进行替换
content = re.sub(pattern, replacer, content)

# 此时，变量 contrent 同样包含了文件的全部内容
# 初始化法律文本的字典结构，可以有一个默认的“编”
filename = os.path.basename(path)
#获取文件名
law_name = filename.split('.')[0]
#创建初始字典
law_dict = {
    law_name:{
        "title": law_name,
        "type": "law",
        "children": [],
    }    
}

# 定义用于匹配标题的正则表达式，包括编、章、节
title_patterns = {
    '编': r'((第[\u4e00-\u9fa5]+编))',
    '章': r'(第[\u4e00-\u9fa5]+章)',
    '节': r'(第[\u4e00-\u9fa5]+节)',
    '条': r'(第[\u4e00-\u9fa5]+条)',
    '项': r'（(.+?)）(.+?)(；|。)',
    '项名': r'(\u3000\u3000)(.+?)(，|。)',
    '附件': r'(附则[\u4e00-\u9fa5]+)'
}


type_to_english = {
    '编': 'part',  # 编 -> part
    '章': 'chapter',  # 章 -> chapter
    '节': 'section',  # 节 -> section
    '条': 'article'  # 条 -> article
}
found_part = False  #检查是否找到编
def parse_section(title_text, text_content, parent_list, title_type):
    global found_part
    pattern = title_patterns.get(title_type)  # 使用get访问，避免 KeyError
    if not pattern or not re.match(pattern, title_text, re.DOTALL):
        return  # 如果没有匹配的模式或标题，直接返回

    if title_type in ['编', '章', '节']:
        new_section = {
        'title': title_text + ' ' + text_content.replace(' ', ''),
        'type': type_to_english.get(title_type, 'section'),
        'children': []  # 初始化 children 列表
    }
    elif title_type == '条':
        new_section = {
        'title': title_text,
        'type': type_to_english.get(title_type, 'section'),
        'children': []  # 初始化 children 列表
    }
      # 找到正确的父级并添加新节或条
    if title_type == '条':
        # “条” 应该挂在最近的父级（“章” 或 “节”）下面
        found_section = False  # 初始化标志位，用于检查是否找到“节”
        found_chapter = True
        if not found_part:
            last_parent = parent_list[-1]
        else:
            last_part = parent_list[-1]
            if len(last_part['children']) == 0:
                last_parent = parent_list[-1]
                found_chapter = False
            else:
                #找到到chapter的情况
                if last_part["children"][-1].get("type") == "chapter":
                    last_parent = last_part["children"][-1]
                else:
                    last_parent = parent_list[-1]
                    found_chapter = False
        #从后往前遍历  
        for child in reversed(last_parent["children"]):
            if child.get('type') == 'section':
                child['children'].append(new_section)
                found_section = True
                break

        if not found_section:
            # 如果没有找到“节”，则添加到最近的“章”下
            if not found_part:
                if parent_list and parent_list[-1].get('type') == 'chapter':
                    parent_list[-1]['children'].append(new_section)
            else:
                #这是找到chapter的情况下
                if found_chapter:
                    last_parent['children'].append(new_section)
                #不存chapter，条直接再编下
                else:
                    if parent_list and parent_list[-1].get('type') == 'part':
                        parent_list[-1]['children'].append(new_section)
                

        # 解析款项，并将结果赋值给新创建的条的 children
        new_section['children'] = parse_items(text_content)
    elif title_type == '编':
        # “编”直接添加到宪法的根部分
        parent_list.append(new_section)
    elif title_type == '章':
        if parent_list != []:
            last_parent = parent_list[-1]
            if last_parent['type'] == 'part':
                found_part = True
        if found_part:
            last_parent['children'].append(new_section)#添加到编下面
        #如果不存在part就挂在根下面
        if not found_part:
            parent_list.append(new_section)
    elif title_type == '节':
        #不存在part的情况
        if not found_part:
        # “节” 应该挂在最近的父级（章）下面
            if parent_list[-1]["type"] == 'chapter':
                parent_list[-1]['children'].append(new_section)#添加到最近的章下
        else:
            last_part = parent_list[-1]
            last_chapter = last_part["children"][-1]
            #添加到最近的章里面
            last_chapter["children"].append(new_section)

#解析每个项
def parse_items(items_content):
    items_list = []
    # 使用正则表达式按“款”分割文本
    items = re.split(r'(?<=。)\s+', items_content)
    for index, item in enumerate(items, start=1):
        item = item.strip()
        if item:
            # 每个款可能有多个项
            sub_items = item.split(' ')
            if len(sub_items) > 1:
                sub_items_list = []
                for sub_index, sub_item in enumerate(sub_items, start=1):
                    sub_item = sub_item.strip()
                    if sub_item:
                        sub_items_list.append({
                            'type': 'item',
                            'title': f"第{sub_index // 2 + 1 }项",
                            'text': sub_item
                        })
                items_list.append({
                    'type': 'paragraph',
                    'title': f"第{index}款",
                    'children': sub_items_list
                })
            else:
                items_list.append({
                    'type': 'paragraph',
                    'title': f"第{index}款",
                    'text': sub_items[0]
                })
    return items_list



# 分割文本为独立的片段
sections = re.split(r'(#{1,6})', content)
processed_sections = [re.sub(r'[\#\']', '', section).strip() for section in sections if section]

# 从宪法的根部分开始解析
root = law_dict[law_name]["children"]
# 解析
# 在主循环中，确保在解析每个节之后，更新parent_list以反映最新的父级
for section in processed_sections:
    if section == '' or section == '-':
        continue
    if len(section) > 1:  # 确保有内容可以分割
        # 分割标题和内容
        section_title, section_content = section.split(' ', 1)
        # 替换换行符为一个空格
        section_content = section_content.replace('\n', ' ')
        # 定义正则表达式模式
        pattern = re.compile(r"中华人民共和国.+法")
        global description
        if pattern.match(section_title):
            description = section_content
        # 确定section的类型，并调用 parse_section
        current_parent_list = root  # 初始父级是宪法的根部分
        for title_type in ['编', '章', '节', '条']:
            pattern = title_patterns.get(title_type)
            if pattern and re.match(pattern, section_title):
                # 调用 parse_section 函数
                parse_section(section_title, section_content, current_parent_list, title_type)
                # 更新parent_list以反映最新的父级
                if title_type in ['编', '章']:
                    parent_list = current_parent_list[-1]['children']
                break 

print(law_dict)
dict_str = json.dumps(law_dict, ensure_ascii=False, indent=4)
with open('E:\法律\法律文件\法律结构2.txt', 'w', encoding='utf-8') as file:
     file.write(dict_str)
#构建item的列表
law_children = []
#将文本处理成lawItem
def store_law_item(law_item, laws_collection, parent_id=None):
    global law_children
    law_item_document = {
        'type': law_item.get('type'),  # 类型
        'title': law_item.get('title'),  # 标题
        'parent': parent_id,  # 父节点的ID
        'children': [],  # 初始化子节点列表
        'startAt': datetime.now(),  # 发布时间
        'endAt':"",
        'revisionHistory': [  # 修订历史
            {'text': law_item.get('text', ''), 'revisedAt': datetime.now()}
        ]
    }
    
    # 如果有文本内容，添加到文档中
    if 'text' in law_item:
        law_item_document['revisionHistory'][0]['text'] = law_item.get('text')

    # 插入文档到数据库
    result = laws_collection.insert_one(law_item_document)
    current_id = str(result.inserted_id)  # 获取新插入文档的_id
    law_children.append(law_item_document)
    # 如果有子项，递归存储子项
    if 'children' in law_item:
        for child in law_item['children']:
            child_id = store_law_item(child, laws_collection, current_id)
            law_item_document['children'].append(child_id)  # 添加子文档ID到当前文档的children列表

    # 更新当前文档，添加子文档ID列表
    laws_collection.update_one(
        {'_id': ObjectId(current_id)},
        {'$set': {'children': law_item_document['children']}}
    )

    return current_id  # 返回当前文档的_id

# 执行数据插入
#获得本次操作的全部lawItem
rootId = store_law_item(law_dict[law_name], law_items_collection)

# 定义Law模型
class Law:
    def __init__(self, title, effectivenessLevel, children=None, publishedAt=None, revisedAt=None, publishDepartment=None, isValid=None, description=None):
        self.title = title
        self.effectivenessLevel = effectivenessLevel
        self.publishDepartment = publishDepartment
        self.children = children if children else []
        self.publishedAt = publishedAt
        self.revisedAt = revisedAt
        self.isValid = isValid
        self.description = description
# 找到最新的修订日期
latest_revision_date = None
for law_item in law_children:
    for revision in law_item['revisionHistory']:
        if latest_revision_date is None or revision['revisedAt'] > latest_revision_date:
            latest_revision_date = revision['revisedAt']


def convert_chinese_date_to_standard(chinese_date_str):
    try:
        # 将中文日期转换为 datetime 对象
        chinese_date_str.replace(" ", "")
        print(chinese_date_str)
        chinese_date = datetime.strptime(chinese_date_str, '%Y年%m月%d日')
        # 将 datetime 对象转换为标准日期格式的字符串
        print(chinese_date)
        return chinese_date
    except ValueError as e:
        print(f"转换错误: {e}")
        raise  # 重新抛出ValueError异常，不再捕获

def get_latest_amendment_date(legal_text):
    pattern = re.compile(r'(\d{4}年\d{1,2}月\d{1,2}日)')
    dates = pattern.findall(legal_text)
    latest_date_str = dates[-1] if dates else None
    # 转换日期格式
    return convert_chinese_date_to_standard(latest_date_str)
# 调用函数并打印结果
latest_amendment_date = get_latest_amendment_date(description)
# 创建Law实例
law = Law(
    title=law_name,
    effectivenessLevel="法律",
    publishDepartment="全国人民代表大会",
    children=rootId,
    publishedAt=latest_amendment_date,  # 假设publishAt是最新时一次的修订时间
    revisedAt=[latest_amendment_date], #假设最新的修订时间是最后一次的时间
    isValid=True,
    description = description
)

# 存储Law模型到数据库（这里需要创建一个新的collection来存储Law模型）
laws_collection = db.laws
result = laws_collection.insert_one(law.__dict__)
law_id = result.inserted_id  # 确保这个变量包含了新插入文档的 _id
law_items_collection.update_one(
        {'parent': None },
        {'$set': {'parent': str(law_id)}}
    )
print(law_id)
print(f"Law模型已创建,id:{law_id}")
#重新置为空
law_children = []

